<template>
  <!-- 定义地图显示容器 -->
  <div id="container"></div>
  <div
    style="position: absolute; top: -230px; left: 0px; z-index: 999"
    ref="mapPop"
    v-show="selectedPoint"
  >
    <el-card style="width: 480px; height: 400px">
      <template #header>
        <div class="card-header">
          {{ selectedPoint ? selectedPoint.properties.content : "" }}
        </div>
      </template>
      <el-scrollbar height="230px">
        <p>
          {{ selectedPoint ? selectedPoint.properties.description : "" }}
        </p>
      </el-scrollbar>
      <template #footer
        ><el-button type="danger" @click="handleDeleteClick">删除图标</el-button
        ><el-button type="primary" @click="handleUpdateClick"
          >编辑图标</el-button
        >
        <el-button type="plain" @click="selectedPoint = null">取消</el-button>
      </template>
    </el-card>
  </div>
</template>
<script setup>
import {
  onMounted,
  reactive,
  toRefs,
  defineEmits,
  watch,
  ref,
  onBeforeUnmount,
} from "vue";
var markerLayer = null; // 点标记
var clickMarkerLayer = null; // 点击点标记
var map = null; // 地图
const emit = defineEmits([
  "markerClick",
  "mapClick",
  "deleteClick",
  "updateClick",
]);

const props = defineProps({
  msg: String,
  pointList: { type: Array, default: () => [] },
  center: { type: Object, default: { lat: 28.674993, lng: 121.4077192 } },
  layerList: { type: Array, default: () => [] },
  showSelectedPoint: { type: Boolean, default: false },
});
const mapPop = ref(null);

const Data = reactive({
  selectedPoint: null,
  imageGroundLayerList: [],
});
const { selectedPoint } = toRefs(Data);

onMounted(() => {
  initMap();
});
onBeforeUnmount(() => {
  map.destroy();
});
const initMap = () => {
  //定义地图中心点坐标
  var mapCenter = new TMap.LatLng(props.center.lat, props.center.lng);
  //定义map变量，调用 TMap.Map() 构造函数创建地图
  map = new TMap.Map(document.getElementById("container"), {
    center: mapCenter, //设置地图中心点坐标
    showControl: true, //显示控件
    baseMap: {
      type: "vector",
      // features: ["base", "building3d", "building2d", "arrow"],
      features: ["base", "arrow"],
    }, //设置地图底图类型
    zoom: 17.2, //设置地图缩放级别
    //pitch: 43.5, //设置俯仰角
    //rotation: 45, //设置地图旋转角度
  });
  map.on("click", (event) => {
    handleMapClick(event);
  });
  initPoints();
  initLayer();
};
const initLayer = () => {
  console.log("begin init layer");
  console.log(props.layerList);
  if (Data.imageGroundLayerList.length > 0) {
    Data.imageGroundLayerList.forEach((layer) => {
      layer.setMap(null);
    });
    Data.imageGroundLayerList = [];
    props.layerList.forEach((layer) => {
      // 创建一个图层
      var imageLatLngBounds = new TMap.LatLngBounds(
        new TMap.LatLng(layer.swlatitude, layer.swlongitude),
        new TMap.LatLng(layer.nelatitude, layer.nelongitude)
      ); // 根据拟覆盖范围的西南角与东北角新建LatLngBounds对象
      var layer = new TMap.ImageGroundLayer({
        map: map,
        bounds: imageLatLngBounds,
        src: layer.imgUrl,
      });
      Data.imageGroundLayerList.push(layer);
    });
  } else {
    props.layerList.forEach((layer) => {
      // 创建一个图层
      console.log(layer);
      var imageLatLngBounds = new TMap.LatLngBounds(
        new TMap.LatLng(layer.swlatitude, layer.swlongitude),
        new TMap.LatLng(layer.nelatitude, layer.nelongitude)
      ); // 根据拟覆盖范围的西南角与东北角新建LatLngBounds对象
      var layer = new TMap.ImageGroundLayer({
        map: map,
        bounds: imageLatLngBounds,
        src: layer.imgUrl,
      });
      Data.imageGroundLayerList.push(layer);
    });
  }
};
const initPoints = () => {
  // 转换 points 数据为 geometries
  const geometries = props.pointList.map((point) => ({
    id: point.id.toString(),
    styleId: point.id,
    position: new TMap.LatLng(point.latitude, point.longitude),
    content: point.content,
    properties: {
      id: point.id,
      content: point.content,
      description: point.description,
      iconPath: point.iconPath,
      imagePath: point.imagePath,
      width: point.width,
      height: point.height,
    },
  }));

  // 创建 MultiMarker 实例
  const styles = geometries.reduce((acc, geom) => {
    acc[geom.styleId] = new TMap.MarkerStyle({
      width: geom.properties.width,
      height: geom.properties.height,
      src:
        geom.properties.iconPath ||
        "http://minio.taishow.cc/school-guider/static/blank.png",
      anchor: { x: geom.properties.width / 2, y: geom.properties.height / 2 },
      direction: "top",
    });
    return acc;
  }, {});
  console.log(styles);
  if (markerLayer) {
    markerLayer.setStyles(styles);
    markerLayer.setGeometries(geometries);
  } else {
    markerLayer = new TMap.MultiMarker({
      map: map, // 指定地图容器
      // 样式定义
      styles: styles,
      // 点标记数据数组
      geometries: geometries,
    });
    markerLayer.on("click", (event) => {
      emit("markerClick", event);
      Data.selectedPoint = event.geometry;
      new Donut({
        map,
        position: new TMap.LatLng(
          event.geometry.position.lat,
          event.geometry.position.lng
        ),
        data: [12, 24],
        minRadius: 13,
        maxRadius: 20,
      });
    });
  }
};

const handleMapClick = (event) => {
  emit("mapClick", event);
  if (props.showSelectedPoint) {
    const geometries = [
      {
        id: "1",
        styleId: "1",
        position: event.latLng,
        content: "选中点",
        properties: {},
      },
    ];
    if (clickMarkerLayer) {
      clickMarkerLayer.setGeometries(geometries);
    } else {
      clickMarkerLayer = new TMap.MultiMarker({
        map: map, // 指定地图容器
        // 样式定义
        styles: {
          1: new TMap.MarkerStyle({
            width: 22,
            height: 31,
            color: "#f00",
            src: "http://minio.taishow.cc/school-guider/static/blank.png",
            anchor: { x: 11, y: 31 },
            direction: "top",
          }),
        },
        // 点标记数据数组
        geometries: geometries,
      });
    }
  }
};
const handleDeleteClick = () => {
  console.log("handleDeleteClick");
  emit("deleteClick", Data.selectedPoint);
  Data.selectedPoint = null;
};
const handleUpdateClick = () => {
  console.log("handleUpdateClick");
  emit("updateClick", Data.selectedPoint);
  Data.selectedPoint = null;
};

watch(
  () => props.pointList,
  () => {
    if (map) {
      initPoints();
    } else {
      initMap();
    }
  },
  { deep: true }
);
watch(
  () => props.center,
  () => {
    if (map) {
      map.setCenter(new TMap.LatLng(props.center.lat, props.center.lng));
    } else {
      initMap();
    }
  },
  { deep: true }
);
watch(
  () => props.layerList,
  () => {
    if (map) {
      initLayer();
    } else {
      initMap();
    }
  },
  { deep: true }
);

function Donut(options) {
  TMap.DOMOverlay.call(this, options);
}

Donut.prototype = new TMap.DOMOverlay();

// 初始化
Donut.prototype.onInit = function (options) {
  this.position = options.position;
  this.data = options.data;
  this.minRadius = options.minRadius || 0;
  this.maxRadius = options.maxRadius || 50;
};

// 销毁时需解绑事件监听
Donut.prototype.onDestroy = function () {
  if (this.onClick) {
    this.dom.removeEventListener(this.onClick);
  }
};

// 创建DOM元素，返回一个DOMElement，使用this.dom可以获取到这个元素
Donut.prototype.createDOM = function () {
  // 经纬度坐标转容器像素坐标
  let pixel = map.projectToContainer(this.position);

  // 使饼图中心点对齐经纬度坐标点
  let left = pixel.getX() - mapPop.value.clientWidth / 2 + "px";
  let top = pixel.getY() - mapPop.value.clientHeight / 2 + "px";
  mapPop.value.style.cssText =
    "position: absolute; top: -230px; left: 0px; z-index: 999";
  return mapPop.value;
};

// 更新DOM元素，在地图移动/缩放后执行
Donut.prototype.updateDOM = function () {
  if (!this.map) {
    return;
  }

  // 经纬度坐标转容器像素坐标
  let pixel = this.map.projectToContainer(this.position);

  // 使饼图中心点对齐经纬度坐标点
  let left = pixel.getX() - this.dom.clientWidth / 2 + "px";
  let top = pixel.getY() - this.dom.clientHeight / 2 + "px";
  this.dom.style.transform = `translate(${left}, ${top})`;
};
</script>
